# coding=utf-8
"""
author: jamon
"""

import asyncio
# from asyncio import AbstractEventLoop

import pygame
from contextlib import suppress

from package.hotfix.reload_mgr import start_reload


class Application(object):

    def __init__(self):
        self.loop = asyncio.get_event_loop()
        # self.net_loop: AbstractEventLoop = asyncio.new_event_loop()
        self.frame_rate: int = 60
        self.scene_events: dict = {}

    def start(self):
        pygame.init()
        worker_future = asyncio.run_coroutine_threadsafe(
            self.listen(), self.loop)

    def add_scene_event(self, name, callback_func):
        self.scene_events[name] = callback_func

    def del_scene_event(self, name):
        if name in self.scene_events:
            del self.scene_events[name]

    async def listen(self):
        clock = pygame.time.Clock()
        try:
            while True:
                events = []
                for event in pygame.event.get():
                    # TODO: 此处可加一些公用事件处理，如退出游戏，刷新界面（热更）
                    events.append(event)
                press_event = pygame.key.get_pressed()
                if press_event[pygame.K_F5]:
                    # 启动热更
                    start_reload()

                cur_events = {}
                cur_events.update(self.scene_events)
                if not cur_events:
                    await asyncio.sleep(0.001)
                else:
                    for _, func in cur_events.items():
                        await func(events=events)
                    await asyncio.sleep(0.001)
                pygame.display.update()
                clock.tick(self.frame_rate)
        except SystemExit:
            pass

    def run(self):
        try:
            self.loop.run_forever()
        finally:
            pending = asyncio.all_tasks(self.loop)
            for task in pending:
                task.cancel()
                with suppress(asyncio.CancelledError):
                    self.loop.run_until_complete(task)
            self.loop.close()
